/*
 * // +-------------------------------------------------------------------------------------------------
 * // |                 有你就好 [ 有节骨乃坚，无心品自端 ]     <http://encoding.wang>
 * // +-------------------------------------------------------------------------------------------------
 * // |                             独在异乡为异客         每逢佳节倍思亲
 * // +-------------------------------------------------------------------------------------------------
 * // |                 联系:   <707069100@qq.com>      <http://weibo.com/513778937>
 * // +-------------------------------------------------------------------------------------------------
 */

// -----------------------------------------------------------------------------------------------------
// +----------------------------------------------------------------------------------------------------
// |                   ErYang出品 属于小极品          共同学习    共同进步
// +----------------------------------------------------------------------------------------------------
// -----------------------------------------------------------------------------------------------------


package wang.encoding.mroot.admin.controller.system.user


import com.alibaba.fastjson.JSONObject
import com.baomidou.mybatisplus.plugins.Page
import org.apache.shiro.authz.annotation.RequiresPermissions
import org.slf4j.Logger
import org.slf4j.LoggerFactory
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.web.bind.annotation.PathVariable
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.ResponseBody
import org.springframework.web.bind.annotation.RestController
import org.springframework.web.servlet.ModelAndView
import org.springframework.web.servlet.mvc.support.RedirectAttributes
import wang.encoding.mroot.admin.common.controller.BaseAdminController
import wang.encoding.mroot.admin.common.util.ShiroSessionUtil
import wang.encoding.mroot.common.annotation.FormToken
import wang.encoding.mroot.common.annotation.RequestLogAnnotation
import wang.encoding.mroot.common.business.ResultData
import wang.encoding.mroot.common.constant.RequestLogConstant
import wang.encoding.mroot.common.exception.ControllerException
import wang.encoding.mroot.common.util.ArrayUtil
import wang.encoding.mroot.common.util.RegexUtil
import wang.encoding.mroot.model.entity.system.Role
import wang.encoding.mroot.model.entity.system.User
import wang.encoding.mroot.model.enums.StatusEnum
import wang.encoding.mroot.model.enums.UserTypeEnum
import wang.encoding.mroot.service.system.RoleService
import wang.encoding.mroot.service.system.UserService
import java.math.BigInteger
import javax.servlet.http.HttpServletRequest


/**
 * 用户控制器
 *
 * @author ErYang
 */
@RestController
@RequestMapping(value = ["/user"])
class UserController : BaseAdminController() {


    @Autowired
    private lateinit var userService: UserService

    @Autowired
    private lateinit var roleService: RoleService


    companion object {

        /**
         * logger
         */
        private val logger: Logger = LoggerFactory.getLogger(UserController::class.java)

        /**
         * 模块
         */
        private const val MODULE_NAME: String = "/user"

        /**
         * 视图目录
         */
        private const val VIEW_PATH: String = "/system/user"

        /**
         * 对象名称
         */
        private const val VIEW_MODEL_NAME: String = "user"
        /**
         * 首页
         */
        private const val INDEX: String = "/index"
        private const val INDEX_URL: String = MODULE_NAME + INDEX
        private const val INDEX_VIEW: String = VIEW_PATH + INDEX
        /**
         * 新增
         */
        private const val ADD: String = "/add"
        private const val ADD_URL: String = MODULE_NAME + ADD
        private const val ADD_VIEW: String = VIEW_PATH + ADD
        /**
         * 保存
         */
        private const val SAVE: String = "/save"
        private const val SAVE_URL: String = MODULE_NAME + SAVE
        /**
         * 修改
         */
        private const val EDIT: String = "/edit"
        private const val EDIT_URL: String = MODULE_NAME + EDIT
        private const val EDIT_VIEW: String = VIEW_PATH + EDIT
        /**
         * 更新
         */
        private const val UPDATE: String = "/update"
        private const val UPDATE_URL: String = MODULE_NAME + UPDATE
        /**
         * 查看
         */
        private const val VIEW: String = "/view"
        private const val VIEW_URL: String = MODULE_NAME + VIEW
        private const val VIEW_VIEW: String = VIEW_PATH + VIEW
        /**
         * 删除
         */
        private const val DELETE: String = "/delete"
        private const val DELETE_URL: String = MODULE_NAME + DELETE

        private const val DELETE_BATCH: String = "/deleteBatch"
        private const val DELETE_BATCH_URL: String = MODULE_NAME + DELETE_BATCH

        /**
         * 授权
         */
        private const val AUTHORIZATION: String = "/authorization"
        private const val AUTHORIZATION_URL: String = MODULE_NAME + AUTHORIZATION
        private const val AUTHORIZATION_VIEW: String = VIEW_PATH + AUTHORIZATION
        /**
         * 保存授权
         */
        private const val AUTHORIZATION_SAVE: String = "/authorizationSave"
        private const val AUTHORIZATION_SAVE_URL: String = MODULE_NAME + AUTHORIZATION_SAVE
        /**
         * 回收站
         */
        private const val RECYCLE_BIN_INDEX: String = "/recycleBin"
        private const val RECYCLE_BIN_INDEX_URL: String = MODULE_NAME + RECYCLE_BIN_INDEX
        private const val RECYCLE_BIN_INDEX_VIEW: String = VIEW_PATH + RECYCLE_BIN_INDEX
        /**
         * 恢复
         */
        private const val RECOVER: String = "/recover"
        private const val RECOVER_URL: String = MODULE_NAME + RECOVER

        private const val RECOVER_BATCH: String = "/recoverBatch"
        private const val RECOVER_BATCH_URL: String = MODULE_NAME + RECOVER_BATCH

        /**
         * 修改密码
         */
        private const val PASSWORD: String = "/password"
        private const val PASSWORD_URL: String = MODULE_NAME + PASSWORD
        private const val PASSWORD_VIEW: String = VIEW_PATH + PASSWORD
        /**
         * 更新密码
         */
        private const val UPDATE_PASSWORD: String = "/updatePassword"
        private const val UPDATE_PASSWORD_URL: String = MODULE_NAME + UPDATE_PASSWORD

        /**
         * 修改昵称
         */
        private const val NICK_NAME: String = "/nickName"
        private const val NICK_NAME_URL: String = MODULE_NAME + NICK_NAME
        private const val NICK_NAME_VIEW: String = VIEW_PATH + NICK_NAME
        /**
         * 更新昵称
         */
        private const val UPDATE_NICK_NAME: String = "/updateNickName"
        private const val UPDATE_NICK_NAME_URL: String = MODULE_NAME + UPDATE_NICK_NAME

    }

    // -------------------------------------------------------------------------------------------------

    /**
     * 列表页面
     *
     * @param request HttpServletRequest
     * @return ModelAndView
     */
    @RequiresPermissions(value = [INDEX_URL])
    @RequestMapping(INDEX)
    @RequestLogAnnotation(module = RequestLogConstant.ADMIN_MODULE,
            title = RequestLogConstant.ADMIN_MODULE_USER_INDEX)
    @Throws(ControllerException::class)
    fun index(request: HttpServletRequest): ModelAndView {
        val modelAndView = ModelAndView(super.initView(INDEX_VIEW))
        super.initViewTitleAndModelUrl(INDEX_URL, MODULE_NAME, request)

        val user = User()
        val username: String? = request.getParameter("username")
        if (null != username && username.isNotBlank()) {
            user.username = username
            modelAndView.addObject("username", username)
        }
        user.status = StatusEnum.NORMAL.key
        val page: Page<User> = userService.list2page(super.initPage(request), user, User.ID, false)!!
        if (null != page.records && page.records.isNotEmpty()) {
            // 数据解密
            page.records = this.aseDecrypt2List(page.records)
        }
        modelAndView.addObject(VIEW_PAGE_NAME, page)
        return modelAndView
    }

    // -------------------------------------------------------------------------------------------------

    /**
     * 添加页面
     *
     * @param request HttpServletRequest
     * @return ModelAndView
     */
    @RequiresPermissions(value = [ADD_URL])
    @RequestMapping(ADD)
    @RequestLogAnnotation(module = RequestLogConstant.ADMIN_MODULE,
            title = RequestLogConstant.ADMIN_MODULE_USER_ADD)
    @FormToken(init = true)
    @Throws(ControllerException::class)
    fun add(request: HttpServletRequest): ModelAndView {
        val modelAndView = ModelAndView(super.initView(ADD_VIEW))
        super.initViewTitleAndModelUrl(ADD_URL, MODULE_NAME, request)
        // 设置上个请求地址
        super.initRefererUrl(request)
        return modelAndView
    }

    // -------------------------------------------------------------------------------------------------

    /**
     * 处理保存
     *
     * @param request HttpServletRequest
     * @param user User
     * @return ModelAndView
     */
    @RequiresPermissions(value = [SAVE_URL])
    @RequestMapping(SAVE)
    @ResponseBody
    @RequestLogAnnotation(module = RequestLogConstant.ADMIN_MODULE,
            title = RequestLogConstant.ADMIN_MODULE_USER_SAVE)
    @FormToken(remove = true)
    @Throws(ControllerException::class)
    fun save(request: HttpServletRequest, user: User): Any {
        if (httpRequestUtil.isAjaxRequest(request)) {
            val failResult: ResultData = ResultData.fail()
            // 创建 User 对象
            val saveUser: User = this.initAddData(request, user)

            // Hibernate Validation  验证数据
            val validationResult: String? = userService.validationUser(saveUser)
            if (null != validationResult && validationResult.isNotBlank()) {
                return super.initErrorHibernateValidationJSONObject(failResult, validationResult)
            }

            // 验证数据唯一性
            val flag: Boolean = this.validationAddData(saveUser, failResult)
            if (!flag) {
                return super.initErrorValidationJSONObject(failResult)
            }

            // 数据加密
            val aseUser: User = userService.aseEncryptData(saveUser)
            // 新增用户 id
            val id: BigInteger? = userService.saveBackId(aseUser)
            return super.initSaveJSONObject(id)
        } else {
            return super.initErrorRedirectUrl()
        }
    }

    // -------------------------------------------------------------------------------------------------

    /**
     * 编辑页面
     *
     * @param id String
     * @param request HttpServletRequest
     * @param redirectAttributes RedirectAttributes
     * @return ModelAndView
     */
    @RequiresPermissions(value = [EDIT_URL])
    @RequestMapping("$EDIT/{id}")
    @RequestLogAnnotation(module = RequestLogConstant.ADMIN_MODULE,
            title = RequestLogConstant.ADMIN_MODULE_USER_EDIT)
    @FormToken(init = true)
    @Throws(ControllerException::class)
    fun edit(@PathVariable(ID_NAME) id: String, request: HttpServletRequest,
             redirectAttributes: RedirectAttributes): ModelAndView {
        val modelAndView = ModelAndView(super.initView(EDIT_VIEW))

        super.initViewTitleAndModelUrl(EDIT_URL, MODULE_NAME, request)
        val idValue: BigInteger? = super.getId(id)
        if (null == idValue || BigInteger.ZERO > idValue) {
            return initValidationResult2Get(modelAndView, redirectAttributes, INDEX_URL)
        }
        // 数据真实性
        val user: User? = userService.getById(idValue)
                ?: return initValidationResult2Get(modelAndView, redirectAttributes, INDEX_URL)
        if (StatusEnum.DELETE.key == user!!.status) {
            return initValidationResult2Get(modelAndView, redirectAttributes, INDEX_URL)
        }
        // 解密
        var decryptUser: User = User.copy2New(user)
        decryptUser = userService.aseDecryptData(decryptUser)
        modelAndView.addObject(VIEW_MODEL_NAME, decryptUser)
        // 设置上个请求地址
        super.initRefererUrl(request)
        return modelAndView
    }

    // -------------------------------------------------------------------------------------------------

    /**
     * 处理更新
     *
     * @param request HttpServletRequest
     * @param user User
     * @return ModelAndView
     */
    @RequiresPermissions(value = [UPDATE_URL])
    @RequestMapping(UPDATE)
    @RequestLogAnnotation(module = RequestLogConstant.ADMIN_MODULE,
            title = RequestLogConstant.ADMIN_MODULE_USER_UPDATE)
    @FormToken(remove = true)
    @Throws(ControllerException::class)
    fun update(request: HttpServletRequest, user: User): Any {
        if (httpRequestUtil.isAjaxRequest(request)) {

            val failResult: ResultData = ResultData.fail()
            // 验证数据
            val idValue: BigInteger? = super.getId(request)
            if (null == idValue || BigInteger.ZERO > idValue) {
                return super.initErrorCheckJSONObject(failResult)
            }
            // 数据真实性
            val userBefore: User = userService.getById(idValue) ?: return super.initErrorCheckJSONObject(failResult)
            if (StatusEnum.DELETE.key == userBefore.status) {
                return super.initErrorCheckJSONObject(failResult)
            }

            // 创建 User 对象
            var editUser = User()
            editUser.id = userBefore.id
            editUser.type = user.type
            val statusStr: String? = super.getStatusStr(request)
            when {
                statusStr.equals(configProperties.bootstrapSwitchEnabled) -> editUser.status = StatusEnum.NORMAL.key
                null == statusStr -> editUser.status = StatusEnum.DISABLE.key
                else -> editUser.status = StatusEnum.DISABLE.key
            }
            editUser = this.initEditData(editUser)

            // Hibernate Validation 验证数据
            val validationResult: String? = userService.validationUser(editUser)
            if (null != validationResult && validationResult.isNotBlank()) {
                return super.initErrorHibernateValidationJSONObject(failResult, validationResult)
            }

            // 修改用户 id
            val id: BigInteger? = userService.updateBackId(editUser)
            return super.initUpdateJSONObject(id)
        } else {
            return super.initErrorRedirectUrl()
        }
    }

    // -------------------------------------------------------------------------------------------------

    /**
     * 查看页面
     *
     * @param id String
     * @param request HttpServletRequest
     * @param redirectAttributes RedirectAttributes
     * @return ModelAndView
     */
    @RequiresPermissions(value = [VIEW_URL])
    @RequestMapping("$VIEW/{id}")
    @RequestLogAnnotation(module = RequestLogConstant.ADMIN_MODULE,
            title = RequestLogConstant.ADMIN_MODULE_USER_VIEW)
    @Throws(ControllerException::class)
    fun view(@PathVariable(ID_NAME) id: String, request: HttpServletRequest,
             redirectAttributes: RedirectAttributes): ModelAndView {
        val modelAndView = ModelAndView(super.initView(VIEW_VIEW))
        super.initViewTitleAndModelUrl(VIEW_URL, MODULE_NAME, request)

        val idValue: BigInteger? = super.getId(id)
        // 验证数据
        if (null == idValue || BigInteger.ZERO > idValue) {
            return initValidationResult2Get(modelAndView, redirectAttributes, INDEX_URL)
        }
        val user: User? = userService.getById(idValue)
                ?: return initValidationResult2Get(modelAndView, redirectAttributes, INDEX_URL)
        // 解密
        var decryptUser: User = User.copy2New(user!!)
        decryptUser = userService.aseDecryptData(decryptUser)
        modelAndView.addObject(VIEW_MODEL_NAME, decryptUser)
        // 设置上个请求地址
        super.initRefererUrl(request)
        return modelAndView
    }

    // -------------------------------------------------------------------------------------------------

    /**
     * 删除
     * @param request HttpServletRequest
     * @param id String
     * @return JSONObject
     */
    @RequiresPermissions(value = [DELETE_URL])
    @RequestMapping("$DELETE/{id}")
    @ResponseBody
    @RequestLogAnnotation(module = RequestLogConstant.ADMIN_MODULE,
            title = RequestLogConstant.ADMIN_MODULE_USER_DELETE)
    @Throws(ControllerException::class)
    fun delete(@PathVariable(ID_NAME) id: String, request: HttpServletRequest): JSONObject? {
        if (super.isAjaxRequest(request)) {
            val idValue: BigInteger? = super.getId(id)
            // 验证数据
            if (null == idValue || BigInteger.ZERO > idValue) {
                super.initErrorCheckJSONObject()
            }
            val user: User? = userService.getById(idValue!!)
            if (null == user) {
                super.initErrorCheckJSONObject()
            }
            // 删除用户 id
            val backId: BigInteger? = userService.removeBackId(user!!.id!!)
            if (null != backId && BigInteger.ZERO < backId) {
                // 异步删除 用户-角色
                controllerAsyncTask.removeByUserId(backId)
            }
            return super.initDeleteJSONObject(backId)
        }
        return super.initReturnErrorJSONObject()
    }

    // -------------------------------------------------------------------------------------------------

    /**
     * 批量删除
     * @param request HttpServletRequest
     * @return JSONObject
     */
    @RequiresPermissions(value = [DELETE_BATCH_URL])
    @RequestMapping(DELETE_BATCH)
    @ResponseBody
    @RequestLogAnnotation(module = RequestLogConstant.ADMIN_MODULE,
            title = RequestLogConstant.ADMIN_MODULE_USER_DELETE_BATCH)
    @Throws(ControllerException::class)
    fun deleteBatch(request: HttpServletRequest): JSONObject? {
        if (super.isAjaxRequest(request)) {
            val idArray: ArrayList<BigInteger>? = super.getIdArray(request)
            // 验证数据
            if (null == idArray || idArray.isEmpty()) {
                super.initErrorCheckJSONObject()
            }
            var flag = false
            if (null != idArray) {
                flag = userService.removeBatch2UpdateStatus(idArray)!!
            }
            return if (flag) {

                // 异步删除 用户-角色
                controllerAsyncTask.removeByUserIdArray(idArray)

                super.initDeleteJSONObject(BigInteger.ONE)
            } else {
                super.initDeleteJSONObject(BigInteger.ZERO)
            }
        }
        return super.initReturnErrorJSONObject()
    }

    // -------------------------------------------------------------------------------------------------

    /**
     * 授权页面
     *
     * @param id String
     * @param request HttpServletRequest
     * @param redirectAttributes RedirectAttributes
     * @return ModelAndView
     */
    @RequiresPermissions(value = [AUTHORIZATION_URL])
    @RequestMapping("$AUTHORIZATION/{id}")
    @RequestLogAnnotation(module = RequestLogConstant.ADMIN_MODULE,
            title = RequestLogConstant.ADMIN_MODULE_USER_AUTHORIZATION)
    @FormToken(init = true)
    @Throws(ControllerException::class)
    fun authorization(@PathVariable(ID_NAME) id: String, request: HttpServletRequest,
                      redirectAttributes: RedirectAttributes): ModelAndView {
        val modelAndView = ModelAndView(super.initView(AUTHORIZATION_VIEW))

        super.initViewTitleAndModelUrl(AUTHORIZATION_URL, MODULE_NAME, request)
        val idValue: BigInteger? = super.getId(id)
        if (null == idValue || BigInteger.ZERO > idValue) {
            return initValidationResult2Get(modelAndView, redirectAttributes, INDEX_URL)
        }
        // 数据真实性
        val user: User? = userService.getById(idValue)
                ?: return initValidationResult2Get(modelAndView, redirectAttributes, INDEX_URL)
        if (StatusEnum.DELETE.key == user!!.status) {
            return initValidationResult2Get(modelAndView, redirectAttributes, INDEX_URL)
        }

        if (UserTypeEnum.ADMIN.key != user.type) {
            super.addFailMessage(redirectAttributes,
                    localeMessageSourceConfiguration.getMessage("message.system.user.authorization.403"))
            modelAndView.viewName = this.initRedirectUrl(INDEX_URL)
            return modelAndView
        }
        // 角色
        val role = Role()
        role.status = StatusEnum.NORMAL.key
        val list: List<Role>? = roleService.listByT(role)
        if (null != list && list.isNotEmpty()) {
            request.setAttribute("roleList", list)
        }
        // 得到用户拥有的角色
        val roleList: Set<Role>? = roleService.listByUserId(user.id!!)
        if (null != roleList && roleList.isNotEmpty()) {
            var hasRole: Role? = null
            for (r: Role in roleList) {
                hasRole = r
            }
            if (null != hasRole) {
                modelAndView.addObject("role", hasRole)
            }
        }

        modelAndView.addObject(VIEW_MODEL_NAME, user)
        // 设置上个请求地址
        super.initRefererUrl(request)
        return modelAndView
    }

// -------------------------------------------------------------------------------------------------

    /**
     * 保存授权
     *
     * @param request HttpServletRequest
     * @param redirectAttributes RedirectAttributes
     * @return ModelAndView
     */
    @RequiresPermissions(value = [AUTHORIZATION_SAVE_URL])
    @RequestMapping(AUTHORIZATION_SAVE)
    @RequestLogAnnotation(module = RequestLogConstant.ADMIN_MODULE,
            title = RequestLogConstant.ADMIN_MODULE_USER_AUTHORIZATION_SAVE)
    @FormToken(remove = true)
    @Throws(ControllerException::class)
    fun authorizationSave(request: HttpServletRequest,
                          redirectAttributes: RedirectAttributes): Any {

        if (httpRequestUtil.isAjaxRequest(request)) {

            val failResult: ResultData = ResultData.fail()
            val idValue: BigInteger? = request.getParameter("id").toBigIntegerOrNull()
            if (null == idValue || BigInteger.ZERO > idValue) {
                return super.initErrorCheckJSONObject(failResult)
            }

            // 数据真实性
            val user: User = userService.getById(idValue) ?: return super.initErrorCheckJSONObject(failResult)
            if (StatusEnum.DELETE.key == user.status) {
                return super.initErrorCheckJSONObject(failResult)
            }

            if (UserTypeEnum.ADMIN.key != user.type) {
                return super.initErrorJSONObject(failResult, "message.system.user.authorization.403")
            }

            // 角色 ID
            val roleId: BigInteger? = request.getParameter("roleId").toBigIntegerOrNull()
            if (null == roleId || BigInteger.ZERO > roleId) {
                // 如果没有选择角色 就是取消授权
                roleService.removeBatchByUserIdAndRoleIdArray(idValue, null)!!
                val resultData: ResultData = ResultData.ok()
                return super.initSucceedJSONObject(resultData, "message.authorization.cancel.succeed")
            }

            // 角色集合
            val roleBigIntegerArray: Array<BigInteger>? = arrayOf(roleId)

            var flag = false
            // 已拥有角色
            val userHasRoleString: String? = roleService.listIdByUserId2String(idValue)
            var userHasRoleArray: Array<BigInteger>? = arrayOf()
            if (null != userHasRoleString) {
                userHasRoleArray = ArrayUtil.string2BigInteger(userHasRoleString)!!
                if (userHasRoleArray.isNotEmpty()) {
                    // 排序
                    userHasRoleArray.sort()
                    // 比较集合
                    flag = roleBigIntegerArray!!.contentEquals(userHasRoleArray)
                }
            }

            // 角色没有发生变化
            if (flag) {
                val resultData: ResultData = ResultData.ok()
                return super.initSucceedJSONObject(resultData, "message.authorization.succeed")
            } else {
                // 删除已有的角色
                if (null != userHasRoleArray && userHasRoleArray.isNotEmpty()) {
                    val hasRules: MutableList<BigInteger> = mutableListOf()
                    hasRules.addAll(userHasRoleArray)
                    hasRules.sort()
                    roleService.removeBatchByUserIdAndRoleIdArray(idValue, hasRules.toTypedArray())!!
                }
                // 授权的角色集合
                roleBigIntegerArray!!.sort()
                val result: Int = roleService.saveBatchByUserIdAndRoleIdArray(idValue, roleBigIntegerArray)!!
                // 授权成功
                return if (0 < result) {
                    val resultData: ResultData = ResultData.ok()
                    super.initSucceedJSONObject(resultData, "message.authorization.succeed")
                } else {
                    super.initErrorJSONObject(failResult, "message.authorization.fail")
                }
            }
        } else {
            return super.initErrorRedirectUrl()
        }
    }

    // -------------------------------------------------------------------------------------------------

    /**
     * 回收站页面
     *
     * @param request HttpServletRequest
     * @return ModelAndView
     */
    @RequiresPermissions(value = [RECYCLE_BIN_INDEX_URL])
    @RequestMapping(RECYCLE_BIN_INDEX)
    @RequestLogAnnotation(module = RequestLogConstant.ADMIN_MODULE,
            title = RequestLogConstant.ADMIN_MODULE_USER_RECYCLE_BIN_INDEX)
    @Throws(ControllerException::class)
    fun recycleBin(request: HttpServletRequest): ModelAndView {
        val modelAndView = ModelAndView(super.initView(RECYCLE_BIN_INDEX_VIEW))
        super.initViewTitleAndModelUrl(RECYCLE_BIN_INDEX_URL, MODULE_NAME, request)

        val user = User()
        val username: String? = request.getParameter("username")
        if (null != username && username.isNotBlank()) {
            user.username = username
            modelAndView.addObject("username", username)
        }
        user.status = StatusEnum.DELETE.key
        val page: Page<User> = userService.list2page(super.initPage(request), user, User.ID, false)!!
        if (null != page.records && page.records.isNotEmpty()) {
            // 数据解密
            page.records = this.aseDecrypt2List(page.records)
        }
        modelAndView.addObject(VIEW_PAGE_NAME, page)
        return modelAndView
    }

    // -------------------------------------------------------------------------------------------------

    /**
     * 恢复
     * @param request HttpServletRequest
     * @param id String
     * @return JSONObject
     */
    @RequiresPermissions(value = [RECOVER_URL])
    @RequestMapping("$RECOVER/{id}")
    @ResponseBody
    @RequestLogAnnotation(module = RequestLogConstant.ADMIN_MODULE,
            title = RequestLogConstant.ADMIN_MODULE_USER_RECOVER)
    @Throws(ControllerException::class)
    fun recover(@PathVariable(ID_NAME) id: String, request: HttpServletRequest): JSONObject? {
        if (super.isAjaxRequest(request)) {
            val idValue: BigInteger? = super.getId(id)
            // 验证数据
            if (null == idValue || BigInteger.ZERO > idValue) {
                super.initErrorCheckJSONObject()
            }
            val user: User? = userService.getById(idValue!!)
            if (null == user) {
                super.initErrorCheckJSONObject()
            }
            // 恢复用户 id
            val backId: BigInteger? = userService.recoverBackId(user!!.id!!)
            return super.initRecoverJSONObject(backId)
        }
        return super.initReturnErrorJSONObject()
    }

    // -------------------------------------------------------------------------------------------------

    /**
     * 批量恢复
     * @param request HttpServletRequest
     * @return JSONObject
     */
    @RequiresPermissions(value = [RECOVER_BATCH_URL])
    @RequestMapping(RECOVER_BATCH)
    @ResponseBody
    @RequestLogAnnotation(module = RequestLogConstant.ADMIN_MODULE,
            title = RequestLogConstant.ADMIN_MODULE_USER_RECOVER_BATCH)
    @Throws(ControllerException::class)
    fun recoverBatch(request: HttpServletRequest): JSONObject? {
        if (super.isAjaxRequest(request)) {
            val idArray: ArrayList<BigInteger>? = super.getIdArray(request)
            // 验证数据
            if (null == idArray || idArray.isEmpty()) {
                super.initErrorCheckJSONObject()
            }
            var flag = false
            if (null != idArray) {
                flag = userService.recoverBatch2UpdateStatus(idArray)!!
            }
            return if (flag) {
                super.initRecoverJSONObject(BigInteger.ONE)
            } else {
                super.initRecoverJSONObject(BigInteger.ZERO)
            }
        }
        return super.initReturnErrorJSONObject()
    }

    // -------------------------------------------------------------------------------------------------

    /**
     * 修改密码页面
     *
     * @param request HttpServletRequest
     * @param redirectAttributes RedirectAttributes
     * @return ModelAndView
     */
    @RequiresPermissions(value = [PASSWORD_URL])
    @RequestMapping(PASSWORD)
    @RequestLogAnnotation(module = RequestLogConstant.ADMIN_MODULE,
            title = RequestLogConstant.ADMIN_MODULE_USER_PASSWORD)
    @FormToken(init = true)
    @Throws(ControllerException::class)
    fun password(request: HttpServletRequest,
                 redirectAttributes: RedirectAttributes): ModelAndView {
        val modelAndView = ModelAndView(super.initView(PASSWORD_VIEW))

        super.initViewTitleAndModelUrl(PASSWORD_URL, MODULE_NAME, request)

        // 当前管理员
        val user: User? = super.getCurrentAdmin()
                ?: return initValidationResult2Get(modelAndView, redirectAttributes, INDEX_URL)
        if (StatusEnum.DELETE.key == user!!.status) {
            return initValidationResult2Get(modelAndView, redirectAttributes, INDEX_URL)
        }
        // 解密
        //var decryptUser: User = User.copy2New(user)
        //decryptUser = userService.aseDecryptData(decryptUser)
        modelAndView.addObject(VIEW_MODEL_NAME, user)
        // 设置上个请求地址
        super.initRefererUrl(request)
        return modelAndView
    }

    // -------------------------------------------------------------------------------------------------

    /**
     * 处理更新密码
     *
     * @param request HttpServletRequest
     * @param user User
     * @return ModelAndView
     */
    @RequiresPermissions(value = [UPDATE_PASSWORD_URL])
    @RequestMapping(UPDATE_PASSWORD)
    @RequestLogAnnotation(module = RequestLogConstant.ADMIN_MODULE,
            title = RequestLogConstant.ADMIN_MODULE_USER_PASSWORD_UPDATE)
    @FormToken(remove = true)
    @Throws(ControllerException::class)
    fun updatePassword(request: HttpServletRequest, user: User): Any {
        if (httpRequestUtil.isAjaxRequest(request)) {
            val failResult: ResultData = ResultData.fail()
            // 验证数据
            val idValue: BigInteger? = super.getId(request)
            if (null == idValue || BigInteger.ZERO > idValue) {
                return super.initErrorCheckJSONObject(failResult)
            }
            // 数据真实性
            val userBefore: User = super.getCurrentAdmin()
                    ?: return super.initErrorCheckJSONObject(failResult)
            if (StatusEnum.DELETE.key == userBefore.status) {
                return super.initErrorCheckJSONObject(failResult)
            }
            // 当前密码
            val oldPassword: String = request.getParameter("oldPassword")
            // 新密码
            val password: String = request.getParameter("password")
            // 确认密码
            val confirmPassword: String = request.getParameter("confirmPassword")

            val flag: Boolean = this.validationUpdatePasswordData(oldPassword.trim(), password.trim(),
                    confirmPassword.trim(), userBefore, failResult)
            if (!flag) {
                return super.initErrorValidationJSONObject(failResult)
            }
            // 创建 User 对象
            val digestPassword: String = digestManageConfiguration.getSha512(oldPassword.trim())
            var editUser = User()
            editUser.id = userBefore.id
            editUser.password = digestPassword
            editUser = this.initEditData(editUser)

            // 修改用户 id
            val id: BigInteger? = userService.updateBackId(editUser)
            if (null != id && BigInteger.ZERO < id) {
                val userNew: User = userService.getById(id)!!
                // 设置 session 中登录用户信息
                //super.initCurrentAdmin(userNew)
                controllerAsyncTask.initCurrentAdmin(userNew, ShiroSessionUtil.getSession())
            }
            return super.initUpdateJSONObject(id)
        } else {
            return super.initErrorRedirectUrl()
        }
    }

    // -------------------------------------------------------------------------------------------------

    /**
     * 修改昵称页面
     *
     * @param request HttpServletRequest
     * @param redirectAttributes RedirectAttributes
     * @return ModelAndView
     */
    @RequiresPermissions(value = [NICK_NAME_URL])
    @RequestMapping(NICK_NAME)
    @RequestLogAnnotation(module = RequestLogConstant.ADMIN_MODULE,
            title = RequestLogConstant.ADMIN_MODULE_USER_NICK_NAME)
    @FormToken(init = true)
    @Throws(ControllerException::class)
    fun nickName(request: HttpServletRequest,
                 redirectAttributes: RedirectAttributes): ModelAndView {
        val modelAndView = ModelAndView(super.initView(NICK_NAME_VIEW))

        super.initViewTitleAndModelUrl(NICK_NAME_URL, MODULE_NAME, request)

        // 当前管理员
        val user: User? = super.getCurrentAdmin()
                ?: return initValidationResult2Get(modelAndView, redirectAttributes, INDEX_URL)
        if (StatusEnum.DELETE.key == user!!.status) {
            return initValidationResult2Get(modelAndView, redirectAttributes, INDEX_URL)
        }
        // 解密
        //var decryptUser: User = User.copy2New(user)
        //decryptUser = userService.aseDecryptData(decryptUser)
        modelAndView.addObject(VIEW_MODEL_NAME, user)
        // 设置上个请求地址
        super.initRefererUrl(request)
        return modelAndView
    }

    // -------------------------------------------------------------------------------------------------

    /**
     * 处理更新昵称
     *
     * @param request HttpServletRequest
     * @param user User
     * @return ModelAndView
     */
    @RequiresPermissions(value = [UPDATE_NICK_NAME_URL])
    @RequestMapping(UPDATE_NICK_NAME)
    @RequestLogAnnotation(module = RequestLogConstant.ADMIN_MODULE,
            title = RequestLogConstant.ADMIN_MODULE_USER_NICK_NAME_UPDATE)
    @FormToken(remove = true)
    @Throws(ControllerException::class)
    fun updateNickName(request: HttpServletRequest, user: User): Any {
        if (httpRequestUtil.isAjaxRequest(request)) {
            val failResult: ResultData = ResultData.fail()
            // 验证数据
            val idValue: BigInteger? = super.getId(request)
            if (null == idValue || BigInteger.ZERO > idValue) {
                return super.initErrorCheckJSONObject(failResult)
            }
            // 数据真实性
            val userBefore: User = super.getCurrentAdmin() ?: return super.initErrorCheckJSONObject(failResult)
            if (StatusEnum.DELETE.key == userBefore.status) {
                return super.initErrorCheckJSONObject(failResult)
            }
            // 密码
            val password: String = request.getParameter("password")
            // 昵称
            val nickName: String = request.getParameter("nickName")

            val flag: Boolean = this.validationUpdateNicknameData(password.trim(), nickName.trim(), userBefore,
                    failResult)
            if (!flag) {
                return super.initErrorValidationJSONObject(failResult)
            }

            // 创建 User 对象
            var editUser = User()
            editUser.id = userBefore.id
            editUser.nickName = nickName.trim()
            editUser = this.initEditData(editUser)

            // 修改用户 id
            val id: BigInteger? = userService.updateBackId(editUser)
            if (null != id && BigInteger.ZERO < id) {
                val userNew: User = userService.getById(id)!!
                // 设置 session 中登录用户信息
                //super.initCurrentAdmin(userNew)
                controllerAsyncTask.initCurrentAdmin(userNew, ShiroSessionUtil.getSession())
            }
            return super.initUpdateJSONObject(id)
        } else {
            return super.initErrorRedirectUrl()
        }
    }

    // -------------------------------------------------------------------------------------------------

    /**
     * 数据 ase 解密 list 数据
     * @param records List<User>
     * @return List<User>
     */
    private fun aseDecrypt2List(records: List<User>): List<User> {
        for (user: User in records) {
            if (null != user.realName && user.realName!!.isNotBlank()) {
                user.realName = aesManageConfiguration.decrypt(user.realName!!)
            }
            if (null != user.phone && user.phone!!.isNotBlank()) {
                user.phone = aesManageConfiguration.decrypt(user.phone!!)
            }
            if (null != user.email && user.email!!.isNotBlank()) {
                user.email = aesManageConfiguration.decrypt(user.email!!)
            }
        }
        return records
    }

    // -------------------------------------------------------------------------------------------------

    /**
     * 验证数据 合法性
     *
     * @param request HttpServletRequest
     * @param user         用户
     * @return User
     */
    private fun initAddData(request: HttpServletRequest, user: User): User {
        val addUser: User = User.copy2New(user)
        addUser.username = addUser.username!!.toLowerCase()
        // 默认昵称
        if (null == addUser.nickName || addUser.nickName!!.isBlank()) {
            addUser.nickName = addUser.username
        }
        // 默认密码
        if (null == addUser.password || addUser.password!!.isBlank()) {
            addUser.password = configProperties.defaultPassword
        }
        if (null != addUser.email && addUser.email!!.isNotBlank()) {
            addUser.email = user.email!!.toLowerCase()
        }
        // ip
        addUser.gmtCreateIp = getIp(request)
        // 创建 User 对象
        return userService.initSaveUser(addUser)
    }

    // -------------------------------------------------------------------------------------------------

    /**
     * 验证数据 合法性
     *
     * @param user         用户
     * @return User
     */
    private fun initEditData(user: User): User {
        val editUser: User = user
        // 创建 User 对象
        return userService.initEditUser(editUser)
    }

    // -------------------------------------------------------------------------------------------------

    /**
     * 验证数据 数据的唯一性
     *
     * @param user         用户
     * @param failResult ResultData
     * @return Boolean true(通过)/false(未通过)
     */
    private fun validationAddData(user: User, failResult: ResultData): Boolean {
        val message: String
        // 用户名是否存在
        val usernameExist: User? = userService.getByUsername(user.username!!.trim().toLowerCase())
        if (null != usernameExist) {
            message = localeMessageSourceConfiguration.getMessage("message.system.user.username.exist")
            failResult.setFail()[configProperties.messageName] = message
            return false
        }

        // 昵称是否存在
        if (null != user.nickName && user.nickName!!.isNotBlank()) {
            val nickNameExist: User? = userService.getByNickName(user.nickName!!.trim().toLowerCase())
            if (null != nickNameExist) {
                message = localeMessageSourceConfiguration.getMessage("message.system.user.nickName.exist")
                failResult.setFail()[configProperties.messageName] = message
                return false
            }
        }

        // 电子邮箱是否存在
        if (null != user.email && user.email!!.isNotBlank()) {
            val emailExist: User? = userService.getByEmail(user.email!!.trim().toLowerCase())
            if (null != emailExist) {
                message = localeMessageSourceConfiguration.getMessage("message.system.user.email.exist")
                failResult.setFail()[configProperties.messageName] = message
                return false
            }
        }

        // 手机号码是否存在
        if (null != user.phone && user.phone!!.isNotBlank()) {
            val phoneExist: User? = userService.getByPhone(user.phone!!.trim())
            if (null != phoneExist) {
                message = localeMessageSourceConfiguration.getMessage("message.system.user.phone.exist")
                failResult.setFail()[configProperties.messageName] = message
                return false
            }
        }
        return true
    }

    // -------------------------------------------------------------------------------------------------

    /**
     * 验证修改密码数据 数据的唯一性 合法性
     *
     * @param oldPassword  旧密码
     * @param password     新密码
     * @param rePassword   确认密码
     * @param failResult ResultData
     * @return 验证结果
     */
    private fun validationUpdatePasswordData(oldPassword: String,
                                             password: String,
                                             rePassword: String,
                                             user: User,
                                             failResult: ResultData): Boolean {
        val message: String
        val oldPasswordFlag: Boolean = RegexUtil.regexValidate(oldPassword, RegexUtil.LETTER_NUM_6TO18_REGEX)
        if (!oldPasswordFlag) {
            message = localeMessageSourceConfiguration.getMessage("message.system.user.oldPassword.pattern.error")
            failResult.setFail()[configProperties.messageName] = message
            return false
        }
        val passwordFlag: Boolean = RegexUtil.regexValidate(password, RegexUtil.LETTER_NUM_6TO18_REGEX)
        if (!passwordFlag) {
            message = localeMessageSourceConfiguration.getMessage("message.system.user.password.pattern.error")
            failResult.setFail()[configProperties.messageName] = message
            return false
        }
        if (rePassword != password) {
            message = localeMessageSourceConfiguration.getMessage("message.system.user.confirmPassword.pattern.error")
            failResult.setFail()[configProperties.messageName] = message
            return false
        }
        // 密码是否正确
        val validationPassword: String = digestManageConfiguration.getSha512(oldPassword)
        if (validationPassword != user.password) {
            message = localeMessageSourceConfiguration.getMessage("message.system.user.oldPassword.pattern.error")
            failResult.setFail()[configProperties.messageName] = message
            return false
        }
        return true
    }

    // -------------------------------------------------------------------------------------------------

    /**
     * 验证修改昵称数据 数据的唯一性 合法性
     *
     * @param password         用户
     * @param nickName         用户
     * @param user         用户
     * @param failResult ResultData
     * @return 验证结果
     */
    private fun validationUpdateNicknameData(password: String,
                                             nickName: String,
                                             user: User,
                                             failResult: ResultData): Boolean {
        val message: String
        val passwordFlag: Boolean = RegexUtil.regexValidate(password, RegexUtil.LETTER_NUM_6TO18_REGEX)
        if (!passwordFlag) {
            message = localeMessageSourceConfiguration.getMessage("message.system.user.oldPassword.pattern.error")
            failResult.setFail()[configProperties.messageName] = message
            return false
        }
        val nickNameFlag: Boolean = RegexUtil.regexValidate(nickName,
                RegexUtil.CN_LETTER_NUM_UL_2TO18_REGEX)
        if (!nickNameFlag) {
            message = localeMessageSourceConfiguration.getMessage("message.system.user.nickName.pattern.error")
            failResult.setFail()[configProperties.messageName] = message
            return false
        }

        // 密码是否正确
        val validationPassword: String = digestManageConfiguration.getSha512(password)
        if (validationPassword != user.password) {
            message = localeMessageSourceConfiguration.getMessage("message.system.user.oldPassword.pattern.error")
            failResult.setFail()[configProperties.messageName] = message
            return false
        }

        // 昵称是否存在
        val nicknameExist: Boolean = userService.propertyUnique(User.NICK_NAME, nickName.trim().toLowerCase(),
                user.nickName!!.toLowerCase())
        if (!nicknameExist) {
            message = localeMessageSourceConfiguration.getMessage("message.system.user.nickName.exist")
            failResult.setFail()[configProperties.messageName] = message
            return false
        }
        return true
    }

    // -------------------------------------------------------------------------------------------------

}

// -----------------------------------------------------------------------------------------------------

// End UserController class

/* End of file UserController.kt */
/* Location: ./src/main/kotlin/wang/encoding/mroot/admin/controller/system/user/UserController.kt */

// -----------------------------------------------------------------------------------------------------
// +----------------------------------------------------------------------------------------------------
// |                           ErYang出品 属于小极品  O(∩_∩)O~~   共同学习    共同进步
// +----------------------------------------------------------------------------------------------------
// -----------------------------------------------------------------------------------------------------
